package com.njiandan.johnson.vr360library.filters.base;

import android.opengl.GLES20;

import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.opengles.GL;

/**
 * author：johnsonZhang on 2017/3/24 15:34
 * email：15915356@qq.com
 */
public class FilterGroup extends AbsFilter {
    private static final String TAG = "FilterGroup";
    private static int[] frameBuffers = null;
    private static int[] frameBufferTextures = null;
    private List<AbsFilter> filters;
    private boolean isRunning;

    public FilterGroup() {
        super();
        filters = new ArrayList<>();
    }

    @Override
    public void init() {
        for (AbsFilter filter : filters) {
            filter.init();
        }
        isRunning = true;
    }

    @Override
    public void destroy() {

    }

    @Override
    public void onDrawFrame(int textureId) {
        runPreDrawTasks();

        if (frameBuffers == null || frameBufferTextures == null) {
            return;
        }

        int size = filters.size();
        int previousTexture = textureId;
        for (int i = 0; i < size; i++) {
            AbsFilter filter = filters.get(i);
            if (i < size - 1) {
                GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight);
                GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffers[i]);
                GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                filter.onDrawFrame(previousTexture);
                GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
                previousTexture = frameBufferTextures[i];
            } else {
                GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight);
                filter.onDrawFrame(previousTexture);
            }
        }
    }

    @Override
    public void onFilterChanged(int surfaceWidth, int surfaceHeight) {
        super.onFilterChanged(surfaceWidth, surfaceHeight);

        int size = filters.size();
        for (int i = 0; i < size; i++) {
            filters.get(i).onFilterChanged(surfaceWidth, surfaceHeight);
        }
        if (frameBuffers != null) {
            destoryFrameBuffers();
        }

        if (frameBuffers == null) {
            frameBuffers = new int[size - 1];
            frameBufferTextures = new int[size - 1];

            for (int i = 0; i < size - 1; i++) {
                GLES20.glGenFramebuffers(1, frameBuffers, i);
            }
        }
    }

    private void destoryFrameBuffers() {
        if (frameBuffers != null) {
            GLES20.glDeleteFramebuffers(frameBuffers.length, frameBuffers, 0);
            frameBuffers = null;
        }
        if (frameBufferTextures != null) {
            GLES20.glDeleteFramebuffers(frameBufferTextures.length, frameBufferTextures, 0);
            frameBufferTextures = null;
        }
    }

    public void addFilter(final AbsFilter filter) {
        if (filter == null) return;
        if (!isRunning) {
            filters.add(filter);
        } else {
            addPreDrawTask(new Runnable() {
                @Override
                public void run() {
                    filter.init();
                    filters.add(filter);
                    onFilterChanged(surfaceWidth, surfaceHeight);
                }
            });
        }
    }
}
